/**
 * @author Bernhard Denner
 * @author Maximilian Csuk
 * @author Konrad Paumann
 */
public class Test {
	
	public static void main(String[] args) {
		Test t = new Test();
		t.output();
	}
	
	public void output() {
		System.out.println("### TEST CASE 1:");
		System.out.println("Build a tree (with servers and laptops):");
		Tree<Server, Laptop> tree = buildTree1();

		
		System.out.println();
		System.out.println("### TEST CASE 2:");
		System.out.println("Print out structure of the tree:");
		printTreePreOrder(tree);
		

		System.out.println();
		System.out.println("### TEST CASE 3:");
		System.out.println("Server with min power consumption:\n" 
							+ minPower(tree, null));
		System.out.println("Laptop with max battery life:\n" 
							+ maxBattery(tree, null));
		
		
		System.out.println();
		System.out.println("### TEST CASE 4:");
		System.out.println("Build another tree (with computers and servers):");
		Tree<Computer, Server> tree2 = new Tree<Computer, Server>(tree.getNodeTitle());
		copy(tree, tree2);
		
		
		System.out.println();
		System.out.println("### TEST CASE 5:");
		System.out.println("Print out structure of this tree:");
		printTreePreOrder(tree2);
		//TODO 6 weitere (optionale) tests
		
	}
	
	/** test case 1
	 * build tree with servers as nodes and laptops as edges
	 */
	public Tree<Server, Laptop> buildTree1() {
		Server s0 = new Server(1024, 100, 20, 130);
		Server s1 = new Server(1536, 100, 20, 110);
		Server s2 = new Server(1536, 110, 20, 100);
		Server s3 = new Server(2048, 120, 20, 120);
		Server s4 = new Server(3072, 140, 20, 140);
		Server s5 = new Server(4096, 150, 20, 30);
		Laptop l1 = new Laptop(1024, 110, 20, 14.1, 160);
		Laptop l2 = new Laptop(2048, 120, 20, 15.4, 180);
		Laptop l3 = new Laptop(3072, 100, 20, 15.4, 120);
		Laptop l4 = new Laptop(2048, 160, 20, 17.0, 400);
		Laptop l5 = new Laptop(4096, 180, 20, 13.3, 350);
		
		// root node
		Tree<Server, Laptop> t = new Tree<Server, Laptop>(s0);
		TreeNodeIterator<Server, Laptop> nit = t.getNodeIterator();
		TreeEdgeIterator<Server, Laptop> eit = t.getEdgeIterator();
		// level 1
		System.out.println("l1 --> s1 eingefuegt: " + nit.insert(l1, s1));
		nit.next();
		// level 2
		System.out.println("l2 --> s2 eingefuegt: " + nit.insert(l2, s2));
		nit.next();
		System.out.println("l3 --> s3 eingefuegt: " + eit.insert(l3, s3));
		eit.next();
		// level 3
		System.out.println("l4 --> s4 eingefuegt: " + nit.insert(l4, s4));
		nit.next();
		// level 4
		System.out.println("l5 --> s5 eingefuegt: " + nit.insert(l5, s5));
		nit.next();
		// wrong insert
		System.out.println("l1 --> s0 eingefuegt: " + nit.insert(l1, s0));
		
		TreeNodeIterator<Server, Laptop> nit2 = t.getNodeIterator();
		TreeEdgeIterator<Server, Laptop> eit2 = t.getEdgeIterator();
		// Level 1
		System.out.println("l2 --> s2 eingefuegt: " + eit2.insert(l2, s2));
		eit2.next();
		// Level 2
		System.out.println("l3 --> s3 eingefuegt: " + nit2.insert(l3, s3));
		nit2.next();
		// Level 3
		System.out.println("l4 --> s4 eingefuegt: " + nit2.insert(l4, s4));
		nit2.next();
		
		return t;
	}
	

	/** test case 2
	 * prints the complete tree in preorder traversal.
	 */ 
	public <N extends Better<? super N>, E> void 
			printTreePreOrder(Tree<N, E> node) {
		
		TreeNodeIterator<N, E> nodeIt = node.getNodeIterator();
		TreeEdgeIterator<N, E> edgeIt = node.getEdgeIterator();
		
		System.out.println("node: " + node.getNodeTitle());
		while (nodeIt.hasNext()) {
			System.out.println("edge: " + edgeIt.next());
			printTreePreOrder(nodeIt.next());
		}
	}
	/** test case 3
	 * returns the server with the minimal power consumption.
	 */
	public Server minPower(Tree<Server, Laptop> tree, Server minPwr) {
	
		TreeNodeIterator<Server, Laptop> nit = tree.getNodeIterator();
		if (minPwr == null) 
			minPwr = tree.getNodeTitle();
		while (nit.hasNext()) {
			Tree<Server, Laptop> curr = nit.next();
			Server tmp = minPower(curr, minPwr);
			if (curr.getNodeTitle().getPowerConsuption() < tmp.getPowerConsuption()) {
				minPwr = curr.getNodeTitle();
			}
		}
		return minPwr;
	}
	/** test case 3
	 * returns the laptop with the maximum battery life.
	 */
	public Laptop maxBattery(Tree<Server, Laptop> tree, Laptop maxBat) {

		TreeEdgeIterator<Server, Laptop> eit = tree.getEdgeIterator();
		TreeNodeIterator<Server, Laptop> nit = tree.getNodeIterator();
		
		while (eit.hasNext()) {
			Tree<Server, Laptop> curN = nit.next();
			Laptop curE = eit.next();

			if (maxBat == null)
				maxBat = curE;

			Laptop tmp = maxBattery(curN, maxBat);
			
			if (curE.getBatteryLife() > tmp.getBatteryLife()) {
				maxBat = tmp;
			}
		}
		return maxBat;
	}
	
	
	/** test case 4
	 * copies the tree structure from t1 to t2 where node and edge titles are swaped
	 */
	public void copy(Tree<Server, Laptop> t1, Tree<Computer, Server> t2) {
		TreeNodeIterator<Server, Laptop> t1n = t1.getNodeIterator();
		TreeEdgeIterator<Server, Laptop> t1e = t1.getEdgeIterator();
		TreeNodeIterator<Computer, Server> t2n = t2.getNodeIterator();
		while(t1n.hasNext()) {
			Tree<Server, Laptop> t1c = t1n.next();
			if (t2n.insert(t1c.getNodeTitle(), t1e.next())) {
				System.out.println(1);
				copy(t1c, t2n.next());	
			} else {
				System.out.println(0);
			}
		}
	}
}
